package tcpMiddleware

import (
	"context"
	tcpServer "go_gateway/service_tcp/server"
	"math"
	"net"
)

//  设定中间件个数
const abortIndex int8 = math.MaxInt8 / 2 //最多 63 个中间件

type TcpHandlerFunc func(*TcpSliceRouterContext)

// TcpSliceRouter
// @Description: Router 路由树节点
//
type TcpSliceRouter struct {
	groups []*TcpSliceGroup
}

// TcpSliceGroup
// @Description: 单个路由节点的信息
//
type TcpSliceGroup struct {
	*TcpSliceRouter
	path     string
	handlers []TcpHandlerFunc
}

// TcpSliceRouterContext
// @Description: tcp服务的ctx
//
type TcpSliceRouterContext struct {
	conn net.Conn
	Ctx  context.Context
	*TcpSliceGroup
	index int8
}

// newTcpSliceRouterContext
// @Description: 创建tcp服务context
// @param conn
// @param r
// @param ctx
// @return *TcpSliceRouterContext
//
func newTcpSliceRouterContext(conn net.Conn, r *TcpSliceRouter, ctx context.Context) *TcpSliceRouterContext {
	newTcpSliceGroup := &TcpSliceGroup{}
	*newTcpSliceGroup = *r.groups[0] //浅拷贝数组指针,只会使用第一个分组
	c := &TcpSliceRouterContext{conn: conn, TcpSliceGroup: newTcpSliceGroup, Ctx: ctx}
	c.Reset()
	return c
}

// Get
// @Description: 获取上下文中的值
// @receiver c
// @param key
// @return interface{}
//
func (c *TcpSliceRouterContext) Get(key interface{}) interface{} {
	return c.Ctx.Value(key)
}

// Set
// @Description: 设置上下文中的值
// @receiver c
// @param key
// @param val
//
func (c *TcpSliceRouterContext) Set(key, val interface{}) {
	c.Ctx = context.WithValue(c.Ctx, key, val)
}

type TcpSliceRouterHandler struct {
	coreFunc func(*TcpSliceRouterContext) tcpServer.TCPHandler
	router   *TcpSliceRouter
}

func (w *TcpSliceRouterHandler) ServeTCP(ctx context.Context, conn net.Conn) {
	c := newTcpSliceRouterContext(conn, w.router, ctx)
	c.handlers = append(c.handlers, func(c *TcpSliceRouterContext) {
		w.coreFunc(c).ServeTCP(ctx, conn)
	})
	c.Reset()
	c.Next()
}

func NewTcpSliceRouterHandler(coreFunc func(*TcpSliceRouterContext) tcpServer.TCPHandler, router *TcpSliceRouter) *TcpSliceRouterHandler {
	return &TcpSliceRouterHandler{
		coreFunc: coreFunc,
		router:   router,
	}
}

// NewTcpSliceRouter
// @Description: 创建新的sliceRouter
// @return *TcpSliceRouter
//
func NewTcpSliceRouter() *TcpSliceRouter {
	return &TcpSliceRouter{}
}

// Group
// @Description: 设置分组
// @receiver g
// @param path
// @return *TcpSliceGroup
//
func (g *TcpSliceRouter) Group(path string) *TcpSliceGroup {
	if path != "/" {
		panic("only accept path=/")
	}
	return &TcpSliceGroup{
		TcpSliceRouter: g,
		path:           path,
	}
}

// Use
// @Description: 添加中间件
// @receiver g
// @param middlewares
// @return *TcpSliceGroup
//
func (g *TcpSliceGroup) Use(middlewares ...TcpHandlerFunc) *TcpSliceGroup {
	g.handlers = append(g.handlers, middlewares...)
	existsFlag := false
	for _, oldGroup := range g.TcpSliceRouter.groups {
		if oldGroup == g {
			existsFlag = true
		}
	}
	if !existsFlag {
		g.TcpSliceRouter.groups = append(g.TcpSliceRouter.groups, g)
	}
	return g
}

// Next
// @Description: 执行下一个中间件
// @receiver c
//
func (c *TcpSliceRouterContext) Next() {
	c.index++
	for c.index < int8(len(c.handlers)) {
		c.handlers[c.index](c)
		c.index++
	}
}

// Abort
// @Description: 跳出中间件执行队列
// @receiver c
//
func (c *TcpSliceRouterContext) Abort() {
	c.index = abortIndex
}

// IsAborted
// @Description: 判断是否跳出
// @receiver c
// @return bool
//
func (c *TcpSliceRouterContext) IsAborted() bool {
	return c.index >= abortIndex
}

// Reset
// @Description: 重置
// @receiver c
//
func (c *TcpSliceRouterContext) Reset() {
	c.index = -1
}
